package com.ruoyi.blog.interceptor;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@Component
public class SignInterceptor implements HandlerInterceptor {
    private static final String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMKz0Z7E+Cv5ZUtcSZdCvbmrGsz+mwpe2H5b2vmnnwSDHR9Uy26ZyOIwjOSxyOTa1p/MYzHvYT0Jzu7FuUEiecMX5NHgwBAaU1mxfMDmuXmZ49m8KUx1fHl9IAopsc0heqVwJixyBevT6NNw7IPbmXGR60uFGf/BdWaTToypAZtLAgMBAAECgYAfhWEgZR8Qb3XYt34qgOGaV3slSOrsyOIfwts2o854uolSczXkF/2PsPB+bdHqSwuIH1zHzstdSGM6AMS3KM+xX5+tgRXPRdBHyUIU7OZInbLAi8t5sX+xOHVK5Gmo7+A3CY/Woq4Wrolopq7BAHR/vU8nSuBGTxIOfrWd2cQtMQJBAOs9kOEIyPb4kHi2zoai3WQ6lIm6rXIHFdcBistiJ9k2zyMgSF+31M1mLvGeK9PNdQHwWZqhgPKgV1REoxyMXt8CQQDT4m/vFYOQbL8+bCMji7Ea5OjF2tMCpywmhFWJiRYd6pbNBqiCuZJ/lVZeN24BlXPCoL1Eeq/BdNjLae3PY40VAkBGjN1RkDftUdjKS1EfMeMh9yurLtBr3VIgfHbqzlJTI8v1pe3uvwxUWawEjMJqMDlCTpog9QTeP1ZRkJA2tKaTAkA5ueRjD8pzS51i5VVBdup+eEUOuopom6EEsWMYgHe9GM+S9jBsxSArkEUikBlxZwVNzjsicAZ4P1xdNvPqX6XtAkACwc2RyaZeGly26aOvAKurg1z+HW8FP6m8jXTpuahRc0dBjBO4Xyd7dYkRQinaRYRXrzY+drtPi+NxLJiY7jS0";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取签名参数
        String sign = request.getHeader("sign");
        if (StrUtil.isBlank(sign) ){
            ServletUtils.renderString(response, AjaxResult.error("签名不可为空！").toString());
            return false;
        }

        // 拼接原参数字符串数据
        StringBuilder sb = new StringBuilder();

        Map<String, Object> parameter = getRequestAllParameter(request);
        TreeMap<String,Object> sortMap = MapUtil.sort(parameter);
        sortMap.forEach((key, value) -> {
            sb.append(key).append("=").append(value).append("&");
        });

        String paramStr = sb.toString().substring(0, sb.length() - 1);

        // RSA 校验
        try{
            RSA rsa = new RSA(PRIVATE_KEY, null);
            byte[] decrypt = rsa.decrypt(sign, KeyType.PrivateKey);
            if (!paramStr.equals(StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8)) ){
                ServletUtils.renderString(response, AjaxResult.error("签名校验失败！").toString());
                return false;
            }
        }catch (Exception e){
            ServletUtils.renderString(response, AjaxResult.error("签名解析错误，请检查客户端密钥是否正确！").toString());
            return false;
        }

        return true;
    }

    private Map<String, Object> getRequestAllParameter(HttpServletRequest request) {
        Map<String, Object> parameter = new HashMap<>();
        Enumeration<String> enumeration = request.getParameterNames();
        while (enumeration.hasMoreElements() ){
            String parameterName = enumeration.nextElement();
            parameter.put(parameterName, request.getParameter(parameterName));
        }
        return parameter;
    }
}
